package com.wang.users.sys.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.common.pojo.BasePojoEnum;
import com.wang.common.util.ConstatFinalUtil;
import com.wang.common.util.RedisUtil;
import com.wang.sys.mapper.AtSysConfigMapper;
import com.wang.sys.pojo.AtSysConfig;
import com.wang.sys.pojo.AtSysConfigQuery;
import com.wang.users.sys.service.AtSysConfigService;
import jakarta.annotation.PostConstruct;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 针对表【at_sys_config(示例_朝代表)】的数据库操作Service实现
 *
 * @author ZjxMi
 */
@Log4j2
@Service
public class AtSysConfigServiceImpl extends ServiceImpl<AtSysConfigMapper, AtSysConfig>
        implements AtSysConfigService {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 重新把数据库中的配置信息放到缓存中
     *
     * ~数据库中的所有数据可能比较多,建议分页取;(只取未删除和启用的)
     * ~一页一页的放
     *
     * @return
     */
    @PostConstruct
    public long reloadCache(){
        IPage<AtSysConfig> page = new Page<>(1, ConstatFinalUtil.BATCH_SIZE);

        AtSysConfigQuery paramQuery = new AtSysConfigQuery();
        AtSysConfig entity = paramQuery.getEntity();
        entity.setStatus(BasePojoEnum.STATUS_ENABLE.getCode());
        entity.setDelFlag(BasePojoEnum.DELFLAG_NO.getCode());
        /* 只是为了获取总页数 */
        List<AtSysConfig> dataList = this.findList(page, paramQuery);
        log.info("==配置信息总条数:{},总页数:{},每页条数:{}==", page.getTotal(), page.getPages(), page.getSize());
        /* 分页取数据 */
        for (int i = 1 ; i <= page.getPages(); i ++) {
            page.setCurrent(i);
            log.info("==分页取数据:总条数:{},总页数:{},当前页:{},每页条数:{}==", page.getTotal(), page.getPages(), page.getCurrent(), page.getSize());
            dataList = this.findList(page, paramQuery);
            for (AtSysConfig dataTemp : dataList) {
                dataTemp.setEnumsJson(null);
                /* 存储到缓存中 */
                this.redisUtil.hashPut(RedisUtil.REDIS_KEY, dataTemp.getId(), JSON.toJSONString(dataTemp));
            }
        }
        return page.getTotal();
    }

    /**
     * model2: jsp --> servlet -->service --> dao --> db, 我们自己封装了一个 PageInfoUtil;
     * MybatisPlus: 不再需要调用 PageInfoUtil,老代码改造的时候是为了整合代码,如果没有老代码,直接写的新代码,采用下面的方式来搞
     *
     * @param page
     * @param query 查询对象
     * @return
     */
    @Override
    public List<AtSysConfig> findList(IPage<AtSysConfig> page, AtSysConfigQuery query) {
        return this.baseMapper.findList(page, query);
    }

    @Override
    public AtSysConfig getById(Serializable id) {
        /* 先到Redis中查询一下是否有值,如果有值直接返回,没有值再查询数据库,同时放到Redis中 */
        String redisValJson = (String) this.redisUtil.hashGet(RedisUtil.REDIS_KEY, id.toString());
        if (StringUtils.isNotEmpty(redisValJson)) {
            /* 查询到了,直接返回 */
            return JSON.parseObject(redisValJson, AtSysConfig.class);
        }
        AtSysConfig sysConfig = super.getById(id);
        /* 存储到缓存中 */
        this.redisUtil.hashPut(RedisUtil.REDIS_KEY, sysConfig.getId(), JSON.toJSONString(sysConfig));
        return sysConfig;
    }

    @Override
    public AtSysConfig findOne(AtSysConfigQuery query) {
        AtSysConfig entity = query.getEntity();
        if (StringUtils.isNotEmpty(entity.getId())) {
            /* 肯定是要根据id查询 */
            return this.getById(entity.getId());
        }
        return this.baseMapper.findOne(query);
    }

    @Override
    public int updateBatch(AtSysConfigQuery query) {
        return this.baseMapper.updateBatch(query);
    }

    @Override
    public int deleteBatch(AtSysConfigQuery query) {
        return this.baseMapper.deleteBatch(query);
    }

    /**
     * 对数据额外处理(非用户填写的数据)
     * @param entity
     */
    private void proccedUpdateData(AtSysConfig entity){
        if (Objects.isNull(entity.getCreateTime())) {
            entity.setCreateTime(new Date());
        }
        entity.setUpdateTime(new Date());
        /* 判断对象是否为空 */
        if (Objects.isNull(entity.getPubTime())) {
            entity.setPubTime(new Date());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(AtSysConfig entity) {
        this.proccedUpdateData(entity);
        /* 新增加的记录默认未删除 */
        entity.setDelFlag(BasePojoEnum.DELFLAG_NO.getCode());
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(AtSysConfig entity) {
        this.proccedUpdateData(entity);
        /* 把数据从缓存中重新Redis */
        this.redisUtil.hashPut(RedisUtil.REDIS_KEY, entity.getId(), JSON.toJSONString(entity));
        return super.updateById(entity);
    }
}